package hu.uniobuda.nik.openday;

import hu.uniobuda.nik.openday.rss.RssArrayAdapter;
import hu.uniobuda.nik.openday.rss.RssFeed;
import hu.uniobuda.nik.openday.rss.RssItem;
import hu.uniobuda.nik.openday.rss.RssReader;
import hu.uniobuda.nik.openday.utils.Config;
import hu.uniobuda.nik.openday.R;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;

import org.xml.sax.SAXException;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.ListView;

public class NewsActivity extends BaseActivity {

	private RssFeed feed;
	private ArrayList<RssItem> rssItems;
	private SharedPreferences mSharedPreferences;
	private int currentHour;
	private boolean forceRefresh = false;;
	private ListView rssListView;
	private RssArrayAdapter adapter;
	LayoutAnimationController controller;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.news);
		setButtonVisible();
		init();
	}

	@Override
	protected void onStart() {
		super.onStart();
		new RssDownloadTask().execute();
	}

	private void init() {
		setOnButtonclick(R.string.update, mOnClickListener);
		Calendar c = Calendar.getInstance();
		currentHour = c.get(Calendar.HOUR_OF_DAY);
		mSharedPreferences = PreferenceManager
				.getDefaultSharedPreferences(this);
		rssListView = (ListView) findViewById(R.id.rssListView);
		rssListView.setDividerHeight(0);

		controller = AnimationUtils.loadLayoutAnimation(this,
				R.anim.list_layout_controller);
		rssListView.setLayoutAnimation(controller);
		
	}

	private OnClickListener mOnClickListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			forceRefresh = true;
			new RssDownloadTask().execute();
		}
	};

	private class RssDownloadTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected void onPreExecute() {
			setBusy(true);
		}

		@Override
		protected Void doInBackground(Void... params) {
			try {
				if (readRssFromFile()) {
					publishNews();
				}
				if (rssItems == null
						|| (mSharedPreferences.getInt("hour", 0) != currentHour)
						|| forceRefresh) {
					readRssFromURL();
					publishNews();
				}
			} catch (SAXException e) {
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			setBusy(false);
			forceRefresh = false;
		}
	}

	private void readRssFromURL() throws SAXException, IOException {
		URL url = new URL(Config.URL_RSS);
		feed = RssReader.read(url);
		rssItems = feed.getRssItems();
		if (rssItems != null) {
			serializeRss();
		}
		saveCurrentHour();
	}

	private void saveCurrentHour() {
		Editor mEditor = mSharedPreferences.edit();
		mEditor.putInt("hour", currentHour);
		mEditor.commit();
	}

	private boolean readRssFromFile() throws SAXException, IOException {
		if (rssItems != null)
			return false;
		deserializeRss();
		return rssItems != null;
	}

	private void publishNews() {
		runOnUiThread(new Runnable() {

			@Override
			public void run() {
				if (rssItems != null) {
					adapter = new RssArrayAdapter(NewsActivity.this, rssItems);
					rssListView.setAdapter(adapter);
				}
			}
		});
	}

	private void serializeRss() {
		FileOutputStream fos;
		try {
			fos = openFileOutput(Config.RSS_FILE_NAME, Context.MODE_PRIVATE);
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			oos.writeObject(rssItems);
			oos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	private void deserializeRss() {
		try {
			FileInputStream fis = openFileInput(Config.RSS_FILE_NAME);
			ObjectInputStream ois = new ObjectInputStream(fis);
			rssItems = (ArrayList<RssItem>) ois.readObject();
			// Friendly time fix
			for (RssItem r : rssItems)
				r.setPubDate(r.getPubDate());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	MotionEvent event;

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		this.event = ev;
		return super.dispatchTouchEvent(ev);
	}
}
